package com.wanban.downloader.manager

import android.text.TextUtils
import android.util.Log
import com.blankj.utilcode.util.NetworkUtils
import com.wanban.downloader.db.DownloadEntity
import com.wanban.downloader.listener.OnBaseDownloadListener
import com.wanban.downloader.listener.OnDownloadListener
import com.wanban.downloader.listener.OnM3U8DownloadListener
import com.wanban.downloader.listener.OnVideoUrlParseListener
import com.wanban.downloader.m3u8.ReTsListDownloadUtilsV2
import com.wanban.downloader.model.DownloadParams
import com.wanban.downloader.model.DownloadType
import com.wanban.downloader.model.M3U8
import com.wanban.downloader.model.Status
import com.wanban.downloader.utils.FileDownloadPathUtils
import com.wanban.downloader.mp4.Mp4DownloadUtils
import com.wanban.downloader.parse.RxM3U8ParseUtilsV2
import com.wanban.downloader.utils.CacheM3U8Utils
import com.wanban.downloader.utils.DownloadUtils
import com.wanban.downloader.utils.ErrorMessage
import com.wanban.downloader.utils.MyThreadUtils
import java.io.File

class DownloadManager(listener: OnDownloadListener?): BaseDownloadManager(listener) {

    /** 解析任务队列 */
    private val parseManagerQueue by lazy { HashMap<String, RxM3U8ParseUtilsV2>() }
    /** ts碎片下载队列 */
    private val tsManagerQueue by lazy { HashMap<String, OnBaseDownloadListener>() }

    override fun getDownloadType(): Int {
        return DownloadType.SELF
    }

    // 下载真正的实现
    override fun executeStart(task: DownloadEntity){
        // 缓存图片
//        cacheCoverImage(task)
        // 先解析视频格式，判断是m3u8还是其他
        val m3U8ParseUtils = RxM3U8ParseUtilsV2(task)
        m3U8ParseUtils.parseVideo(object : OnVideoUrlParseListener {
            override fun onSuccess(m3u8: M3U8?) {
                val tsCount = m3u8?.tsList?.size?:0
                Log.d(TAG, "解析完成 => tsSize => $tsCount")
                // 解析完成就删除任务
                removeParseManager(task.url)
                // 如果用户点击了删除任务，不在继续执行
                if (task.state == Status.DELETE) return
                // 更新数据实体
                task.m3u8 = m3u8
                // 如果解析任务中找不到对应任务，说明用户点击了暂停
                if (task.state == Status.STOP) {
                    // 更新内容，但不发送消息
                    updateTask(task)
                    return
                }
                // 更改状态
                if (task.m3u8?.isM3U8 == true) {
                    // 继续下载碎片
                    ready2Download(task)
                } else {
                    downloadMp4(task)
                }
            }

            override fun onError(error: String) {
                Log.e(TAG, "解析失败 => 错误信息：$error")
                // 解析完成就删除任务
                removeParseManager(task.url)
                // 删除可能因解析已经生成的文件，下载解析重新开始
                deleteDownloadCacheAndFile(task)
                if (task.state == Status.DELETE || task.state == Status.STOP) return
                if (NetworkUtils.isConnected()) {
                    task.errorMsg = error
                    task.m3u8 = null
                    onErrorStatus(task)
                } else {
                    task.isNetworkError = true
                    task.errorMsg = ErrorMessage.ERROR_MSG_DISCONNECT_NET
                    task.m3u8 = null
//                    onErrorStatus(task, false)
                    onPendingStatus(task)
                }
            }
        })
        // 加入队列
        parseManagerQueue[task.url] = m3U8ParseUtils
    }

    override fun stopDownloadTask(url: String) {
        if (parseManagerQueue.containsKey(url)) {
            val manager = parseManagerQueue.remove(url)
            manager?.cancelParse()
        }
        if (tsManagerQueue.containsKey(url)) {
            val parseUtils = tsManagerQueue[url]
            parseUtils?.cancelAllTask()
        }
    }


    override fun excSelfDeleteTask(url: String) {
        if (parseManagerQueue.containsKey(url)) {
            val manager = parseManagerQueue.remove(url)
            manager?.cancelParse()
        }
        if (tsManagerQueue.containsKey(url)) {
            val parseUtils = tsManagerQueue.remove(url)
            parseUtils?.cancelAllTask()
        }
//        if (!executor.isShutdown) {
//            executor.shutdownNow()
//        }
    }

    // 删除fileName内的全部文件
    override fun deleteTaskFile(task: DownloadEntity) {
        if (task.fileDirPath == null) return
        deleteDownloadCacheAndFile(task)
    }

    private fun deleteDownloadCacheAndFile(task: DownloadEntity){
        MyThreadUtils.executeSingleTask {
            Thread.sleep(2000)
            FileDownloadPathUtils.deleteDownloadFile(task.fileDirPath)
            // 删除缓存
            CacheM3U8Utils.clearCacheM3U8(task.getFileName())
            return@executeSingleTask 1
        }
    }


    private fun ready2Download(task: DownloadEntity) {
        removeTsUtils(task.url)
        downloadTsList(task)
    }


    /**
     * m3u8的下载任务
     */
    private fun downloadTsList(task: DownloadEntity) {
        val tsDownloadUtils = ReTsListDownloadUtilsV2(task, object: OnM3U8DownloadListener {
            override fun onStart(url: String) {
                onStartStatus(url)
            }

            override fun onError(url: String, errorMsg: String) {
                Log.e(TAG, "onError...$errorMsg，errorTimes: ${task.retryTime}")

                if (!NetworkUtils.isConnected()) { // 无网络的情况直接重置状态，不在报错，也不在继续执行
                    Log.e("NewNetwork", "已经断开了网络连接...")
                    task.errorMsg = ErrorMessage.ERROR_MSG_DISCONNECT_NET
                    task.isNetworkError = true
                    removeTsUtils(url)
                    onPendingStatus(task)
                    return
                }


                if (task.retryTime < DownloadParams.maxRetryTimes) {
                    task.retryTime++
                    removeTsUtils(url)
                    // 尝试自动修复失败的下载
                    Log.e("ReOkHttpTsV2", "${task.getFileName()} -> 下载失败，准备进行第${task.retryTime}次重试...")
                    downloadTsList(task)
                } else {
                    removeTsUtils(url)
                    task.errorMsg = errorMsg
                    onErrorStatus(task, !task.isNetworkError)
                }
//                removeTsUtils(url)
//                task.errorMsg = errorMsg
//                onErrorStatus(task, !task.isNetworkError)
            }

            override fun onProgress(url: String, speed: Long, percent: Float, currentLength: Long) {
                onProgressStatus(url, speed, percent, currentLength)
            }

            override fun onSuccess(task: DownloadEntity) {
                Log.e(TAG, "onSuccess...下载成功")
                removeTsUtils(task.url)
                onSuccessStatus(task)
            }
        })
        tsManagerQueue[task.url] = tsDownloadUtils
    }


    private fun downloadMp4(task: DownloadEntity){
        val mp4DownloadUtils = Mp4DownloadUtils(task, object: OnM3U8DownloadListener {
            override fun onStart(url: String) {
                onStartStatus(url)
            }

            override fun onError(url: String, errorMsg: String) {
                Log.e(TAG, "onError...$errorMsg  停止下载")
                removeTsUtils(url)
                if (!NetworkUtils.isConnected()) {
                    task.isNetworkError = true
                    task.errorMsg = ErrorMessage.ERROR_MSG_DISCONNECT_NET
                    onErrorStatus(task, false)
                } else {
                    task.errorMsg = errorMsg
                    onErrorStatus(task)
                }
            }

            override fun onProgress(url: String, speed: Long, percent: Float, currentLength: Long) {
                onProgressStatus(url, speed, percent, currentLength)
            }

            override fun onSuccess(task: DownloadEntity) {
                Log.d(TAG, "onSuccess...下载成功")
                removeTsUtils(task.url)
                onSuccessStatus(task)
            }
        })

        tsManagerQueue[task.url] = mp4DownloadUtils
    }



    // 删除队列中的解析任务
    private fun removeParseManager(url: String?){
        if (parseManagerQueue.containsKey(url)) {
            val m3U8ParseUtils = parseManagerQueue.remove(url)
            m3U8ParseUtils?.cancelParse()
        }
    }
    private fun removeTsUtils(url: String){
        if (tsManagerQueue.containsKey(url)) {
            val tsManager = tsManagerQueue.remove(url)
            tsManager?.cancelAllTask()
        }
    }

    // 通过 构造方法 配置核心参数
//    private val executor by lazy { ThreadPoolExecutor(1, 2, 0L, TimeUnit.MILLISECONDS, LinkedBlockingQueue()) }
    private fun cacheCoverImage(task: DownloadEntity){
        try {
            if (TextUtils.isEmpty(task.coverUrl)) return
            val coverImagePath = FileDownloadPathUtils.getCoverFilePath(task.fileDirPath)?:return
            val coverImageFile = File(coverImagePath)
            if (coverImageFile.exists() && coverImageFile.isFile && coverImageFile.length() > 100) { // 下载成功
                return
            }
            // 需要下载图片
            val runnable = DownloadUtils(task.coverUrl!!, coverImagePath, object: DownloadUtils.OnDownloadListener {
                override fun onProgress(url: String, progress: Int) {

                }

                override fun onError(url: String, errorMsg: String) {
                    coverImageFile.delete()
                }

                override fun onComplete(url: String, totalLength: Long) {

                }
            })
//            executor.submit(runnable)
        } catch (e: Exception) {
            e.printStackTrace()
        }
    }
}